package org.feng.handler;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.PlainSelect;
import org.feng.annotions.DataPermission;
import org.feng.common.RequestHeaderUserInfo;
import org.feng.common.RequestHolder;
import org.feng.interceptor.MyDataPermissionHandler;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 数据权限处理器
 *
 * @author fengjinsong
 */
@Slf4j
public class SimpleDataPermissionHandler implements MyDataPermissionHandler {

    @Override
    public Expression getSqlSegmentWithPermission(PlainSelect plainSelect, String whereStatement) {
        return this.getSqlSegmentByPlainSelect(plainSelect, whereStatement);
    }

    @SneakyThrows(Exception.class)
    private Expression getSqlSegmentByPlainSelect(PlainSelect plainSelect, String whereStatement) {
        // 待执行 SQL Where 条件表达式
        Expression where = plainSelect.getWhere();
        if (where == null) {
            where = new HexValue(" 1 = 1 ");
        }
        log.info("开始进行权限过滤,where: {},mappedStatementId: {}", where, whereStatement);
        //获取mapper名称
        String className = whereStatement.substring(0, whereStatement.lastIndexOf("."));
        //获取方法名
        String methodName = whereStatement.substring(whereStatement.lastIndexOf(".") + 1);
        Table fromItem = (Table) plainSelect.getFromItem();
        // 有别名用别名，无别名用表名，防止字段冲突报错
        Alias fromItemAlias = fromItem.getAlias();
        String mainTableName = fromItemAlias == null ? fromItem.getName() : fromItemAlias.getName();
        //获取当前mapper 的方法
        Method[] methods = Class.forName(className).getMethods();
        //遍历判断mapper 的所以方法，判断方法上是否有 DataPermission
        for (Method m : methods) {
            if (Objects.equals(m.getName(), methodName)) {
                boolean annotationPresent = m.isAnnotationPresent(DataPermission.class);
                if(!annotationPresent){
                    return where;
                }

                DataPermission annotation = m.getAnnotation(DataPermission.class);
                String permissionFieldName = annotation.permissionFieldName();
                // 当前用户信息
                RequestHeaderUserInfo userInfo = RequestHolder.REQUEST_HEADER_USER_INFO_THREAD_LOCAL.get();
                // 查看自己的数据
                //  = 表达式
                EqualsTo usesEqualsTo = new EqualsTo();
                usesEqualsTo.setLeftExpression(new Column(mainTableName + "." + permissionFieldName));
                usesEqualsTo.setRightExpression(new LongValue(String.valueOf(userInfo.getUserId())));
                return new AndExpression(where, usesEqualsTo);
            }
        }
        //说明无权查看，
        where = new HexValue(" 1 = 2 ");
        return where;
    }
}
